package cn.sciento.wechat.service.impl;

import com.alibaba.fastjson.JSON;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import cn.sciento.wechat.dto.AllTemplatesDTO;
import cn.sciento.wechat.dto.DefaultResultDTO;
import cn.sciento.wechat.dto.DelTemplateDTO;
import cn.sciento.wechat.dto.GetTemplateIdDTO;
import cn.sciento.wechat.dto.GetTemplateIdResultDTO;
import cn.sciento.wechat.dto.JsTicketDTO;
import cn.sciento.wechat.dto.TemplateSendDTO;
import cn.sciento.wechat.dto.TemplateSendResultDTO;
import cn.sciento.wechat.dto.TokenDTO;
import cn.sciento.wechat.service.BaseWechatService;
import cn.sciento.wechat.util.Sha1Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class BaseWechatServiceImpl implements BaseWechatService {
  protected final String WX_TOKEN_KEY = "hips:token:wechat-official";
  
  private static final Logger logger = LoggerFactory.getLogger(BaseWechatServiceImpl.class);
  
  @Resource(name = "wdRestTemplate")
  RestTemplate restTemplate;
  
  @Resource(name = "wdRedisTemplate")
  protected RedisTemplate redisTemplate;
  
  public String wechatValid(String signature, String timestamp, String nonce, String echostr, String token) {
    String[] signArgs = { timestamp, nonce, token };
    Arrays.sort((Object[])signArgs);
    String digest = Sha1Utils.encodeSHA1(String.join("", (CharSequence[])signArgs));
    if (digest.equalsIgnoreCase(signature))
      return echostr; 
    return "";
  }
  
  public TokenDTO getTokenWithCache(String appId, String appSecret) {
    String key = "hips:token:wechat-official:" + appId;
    ValueOperations<String, TokenDTO> valueOperations = this.redisTemplate.opsForValue();
    if (this.redisTemplate.hasKey(key).booleanValue()) {
      TokenDTO tokenDTO1 = (TokenDTO)valueOperations.get(key);
      return tokenDTO1;
    } 
    TokenDTO tokenDTO = (TokenDTO)this.restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret, TokenDTO.class);
    if (tokenDTO != null && StringUtils.isNotBlank(tokenDTO.getAccess_token())) {
      long expires_in = tokenDTO.getExpires_in().longValue();
      valueOperations.set(key, tokenDTO);
      this.redisTemplate.expire(key, expires_in, TimeUnit.SECONDS);
    } 
    return tokenDTO;
  }
  
  public TokenDTO getToken(String appId, String appSecret) {
    return (TokenDTO)this.restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret, TokenDTO.class);
  }
  
  public TokenDTO getTokenFromThirdPart(String authUrl) {
    return (TokenDTO)this.restTemplate.getForObject(authUrl, TokenDTO.class);
  }
  
  public GetTemplateIdResultDTO getTemplateId(String templateIdShort, String accessToken) {
    return (GetTemplateIdResultDTO)this.restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=" + accessToken, new HttpEntity(JSON.toJSONString((new GetTemplateIdDTO()).setTemplate_id_short(templateIdShort))), GetTemplateIdResultDTO.class);
  }
  
  public AllTemplatesDTO getAllTemplate(String accessToken) {
    return (AllTemplatesDTO)this.restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=" + accessToken, AllTemplatesDTO.class);
  }
  
  public DefaultResultDTO deleteTemplateById(String templateId, String accessToken) {
    return (DefaultResultDTO)this.restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token=" + accessToken, new HttpEntity(JSON.toJSONString((new DelTemplateDTO()).setTemplate_id(templateId))), DefaultResultDTO.class);
  }
  
  public TemplateSendResultDTO sendTemplateMessage(TemplateSendDTO templateSendDTO, String accessToken) {
    return (TemplateSendResultDTO)this.restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken, new HttpEntity(JSON.toJSONString(templateSendDTO)), TemplateSendResultDTO.class);
  }
  
  public List<TemplateSendResultDTO> batchSendTemplateMessage(List<TemplateSendDTO> templateSendDTOs, String accessToken) {
    return (List<TemplateSendResultDTO>)templateSendDTOs.stream().map(j -> (TemplateSendResultDTO)this.restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken, new HttpEntity(JSON.toJSONString(j)), TemplateSendResultDTO.class)).collect(Collectors.toList());
  }
  
  public JsTicketDTO getjsapiTicketWithCache(String accessToken, String appId) {
    String key = "hips:token:wechat-official:jsapi-ticket:" + appId;
    ValueOperations<String, JsTicketDTO> valueOperations = this.redisTemplate.opsForValue();
    if (this.redisTemplate.hasKey(key).booleanValue()) {
      JsTicketDTO jsTicketDTO1 = (JsTicketDTO)valueOperations.get(key);
      return jsTicketDTO1;
    } 
    JsTicketDTO jsTicketDTO = (JsTicketDTO)this.restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=" + accessToken + "&type=jsapi", JsTicketDTO.class);
    if (jsTicketDTO != null && StringUtils.isNotBlank(jsTicketDTO.getTicket())) {
      long expires_in = jsTicketDTO.getExpires_in();
      valueOperations.set(key, jsTicketDTO);
      this.redisTemplate.expire(key, expires_in, TimeUnit.SECONDS);
    } 
    return jsTicketDTO;
  }
}
